package modele;

import java.util.ArrayList;
import java.util.Scanner;

/**
 * 
 * @author Florence Delrieu & Coralie Micouin
 * 
 */
public class Terme {

	// L'id d'un nouveau terme ne doit pas etre confondu avec un precedent. Il
	// est donc gere de maniere statique dans la classe Terme, et est incremente
	// par le constructeur lui meme.
	private static int ID_TERME_SUIVANT = 1;

	private int idTerme;
	private String terme;
	private String positions;
	private String frequences;
	private String tf;
	private String idf;
	private String score;

	/**
	 * constructeur [pendant le parsage xml]
	 * 
	 * @param terme
	 */
	public Terme(String terme) {
		this.idTerme = Terme.ID_TERME_SUIVANT++;
		this.terme = terme;
		// On initialise les 4 chaines a "", sinon elles contiendront
		// "nulln1p1p3..."
		this.positions = "";
		this.frequences = "";
		this.tf = "";
		this.idf = "";
		this.score = "";
	}

	public Terme(String terme, int idTerme, String positions,
			String frequences, String idf, String tf, String score) {
		this.idTerme = idTerme;
		this.terme = terme;
		this.positions = positions;
		this.frequences = frequences;
		this.tf = tf;
		this.idf = idf;
		this.score = score;
	}

	public int getIdTerme() {
		return idTerme;
	}

	public void setIdTerme(int idTerme) {
		this.idTerme = idTerme;
	}

	public String getTerme() {
		return terme;
	}

	public void setTerme(String terme) {
		this.terme = terme;
	}

	public String getPositions() {
		return positions;
	}

	public void setPositions(String positions) {
		this.positions = positions;
	}

	public String getFrequences() {
		return frequences;
	}

	public void setFrequences(String frequences) {
		this.frequences = frequences;
	}

	public String getTf() {
		return tf;
	}

	public void setTf(String tf) {
		this.tf = tf;
	}

	public String getIdf() {
		return idf;
	}

	public void setIdf(String idf) {
		this.idf = idf;
	}

	public String getScore() {
		return score;
	}

	public void setScore(String score) {
		this.score = score;
	}

	/**
	 * ajouter un nouveau noeud au terme
	 * 
	 * @param noeud
	 */
	public void addNoeud(int noeud) {
		this.positions += "n" + noeud;
		this.frequences += "n" + noeud;
	}

	/**
	 * ajouter une nouvelle position au terme
	 * 
	 * @param position
	 */
	public void addPosition(int position) {
		this.positions += "p" + position;
	}

	/**
	 * ajouter une nouvelle frequence au terme
	 * 
	 * @param frequence
	 */
	public void addFrequence(int frequence) {
		this.frequences += "f" + frequence;
	}

	/**
	 * ajouter un nouveau tf au terme
	 * 
	 * @param tf
	 */
	public void addTf(double tf) {
		this.tf += "t" + tf;
	}

	/**
	 * ajouter un nouveau idf au terme
	 * 
	 * @param idf
	 */
	public void addIdf(double idf) {
		this.idf += "i" + idf;
	}

	// ////////////////////////////////////////////
	// METHODES DE RECUPERATION D'INFOS //
	// ////////////////////////////////////////////

	/**
	 * Methode pour recuperer une Arraylist d'id de noeuds dans lesquels le
	 * terme est present
	 * 
	 * @return
	 */
	public ArrayList<Integer> getIdNoeuds() {
		ArrayList<Integer> noeuds = new ArrayList<Integer>();
		String pos = positions;
		// on enleve tous les "n" (mais on les remplace par un espace pour
		// pouvoir utiliser nextInt)
		pos = pos.replace("n", " ");

		// et on enleve toutes les positions (mais on les remplace par un espace
		// pour pouvoir utiliser nextInt)
		pos = pos.replaceAll("p[0-9]*", " ");
		Scanner scanner = new Scanner(pos);

		while (scanner.hasNextInt()) {
			noeuds.add(scanner.nextInt());
		}

		scanner.close();

		return noeuds;
	}

	public ArrayList<Integer> getPositionsDansNoeud(int noeud) {
		ArrayList<Integer> listePositions = new ArrayList<Integer>();
		String[] splitDebut = this.positions.split("n" + noeud + "p");
		if (splitDebut.length != 1) {
			String splitFin = splitDebut[1].split("n")[0];
			String[] splitP = splitFin.split("p");
			for (String pos : splitP) {
				listePositions.add(Integer.parseInt(pos));
			}
		}
		return listePositions;
	}

	public double getScorePourNoeud(int idNoeud) {
		double scorePourNoeud = 0;
		// La chaine a decouper est de la forme n1s3n4s1n6s2
		// Si l'on veut le score du noeud 4, on split avec le separateur n4s, ce
		// qui donne n1s3 et 1n6s2. C'est le deuxieme resultat qui nous
		// interesse, on va le splitter a nouveau avec le separateur n, ce qui
		// va donner 1 et 6s2. On recupere le premier resultat de ce split. Si
		// jamais la chaine ne contenait pas n4s, c'est que le noeud ne contient
		// pas le terme, on renvoie 0. Si le deuxieme split ne renvoie qu'une
		// chaine, c'est que le noeud est le tout dernier de la chaine ; on
		// recuperera bien 1 ("1".split("n") donne "1")
		String[] rechercheNoeud = this.score.split("n" + idNoeud + "s");
		if (rechercheNoeud.length != 1) {
			scorePourNoeud = Double
					.parseDouble(rechercheNoeud[1].split("n")[0]);
		}
		return scorePourNoeud;
	}

	// tests

	public void testGetIdNoeuds() {
		// test avec set
		setPositions("n2p236n654p5pp96p5n56");

		ArrayList<Integer> n = getIdNoeuds();
		for (int i = 0; i < n.size(); i++) {
			System.out.println(n.get(i));
		}
		System.out.println("\n");
		// test avec add
		setPositions("");
		addNoeud(56);
		addNoeud(5);
		addPosition(589);
		addNoeud(5);
		addPosition(5);
		addPosition(45);
		addPosition(85);
		addNoeud(45);

		n = getIdNoeuds();
		for (int i = 0; i < n.size(); i++) {
			System.out.println(n.get(i));
		}
	}

	public static void main(String[] args) {
		Terme t = new Terme("mot1");
		t.testGetIdNoeuds();
	}

	@Override
	public boolean equals(Object o) {
		if (o == null || o.getClass() != Terme.class) {
			return false;
		}
		return this.idTerme == ((Terme) o).getIdTerme();
	}
}
